package BlockingQueue;


class MyBlockingQueue{//阻塞队列
    private String[] elems = null;

    private int head = 0;
    private int tail = 0;
    private int size = 0;

    private Object locker = new Object();
    public MyBlockingQueue(int capacity){
        elems = new String[capacity];
    }

    public void put(String elem) throws InterruptedException {

        synchronized (locker){
            while (size >= elems.length){//用wait进行再一次检查
                //队列满了，进行阻塞
                locker.wait();//队列出一个元素就能唤醒
            }

            elems[tail] = elem;
            tail++;

            if (tail >= elems.length){
                tail = 0;
            }
            size++;
            locker.notify();//唤醒take
        }

    }

    public String take() throws InterruptedException {
        String elem = null;

        synchronized (locker){
            while (size == 0){
            //队列为空 进行阻塞
                locker.wait();//队列进一个元素就能唤醒
            }


            elem = elems[head];
            head++;
            if(head >= elems.length){
                head = 0;
            }
            size--;
            locker.notify();//唤醒put
        }

        return elem;
    }

}
public class   BlockingQueue {
    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue myBlockingQueue = new MyBlockingQueue(1000);
        /*myBlockingQueue.put("aaa");
        myBlockingQueue.put("bbb");
        myBlockingQueue.put("ccc");

        System.out.println(myBlockingQueue.take());
        System.out.println(myBlockingQueue.take());
        System.out.println(myBlockingQueue.take());*/

        //生产者
        Thread t1 = new Thread(()->{
            int n = 1;
            while (true){
                try {
                    myBlockingQueue.put(n +"");
                    System.out.println("生产元素" + n);
                    n++;
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //消费者
        Thread t2 = new Thread(() ->{
            while (true){
                try {
                    String n = myBlockingQueue.take();
                    System.out.println("消费产品" + n);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        t1.start();
        t2.start();
    }
}
